package com.truthbean.log.log4j2;

import com.truthbean.log.Logger;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Marker;
import org.apache.logging.log4j.MarkerManager;
import org.apache.logging.log4j.spi.AbstractLogger;
import org.apache.logging.log4j.spi.ExtendedLoggerWrapper;

/**
 * @author TruthBean
 * @since 0.0.1
 */
public class Log4j2Impl implements Logger {

    /**
     * logger using this class
     */
    private static final org.apache.logging.log4j.Logger LOGGER = LogManager.getLogger(Log4j2Impl.class);

    private org.apache.logging.log4j.Logger log;

    private static boolean isSpi = true;
    private ExtendedLoggerWrapper spiLog;

    /**
     * test TEST_LOGGER class
     */
    static {
        if (!(LOGGER instanceof AbstractLogger)) {
            isSpi = false;
            LOGGER.error(LOGGER.getClass() + " is not log4j2 spi");
        }
    }

    /**
     * marker
     */
    private static final Marker MARKER = MarkerManager.getMarker(com.truthbean.log.LoggerFactory.MARKER);

    private static final String FQCN = Log4j2Impl.class.getName();

    public Log4j2Impl() {
    }

    @Override
    public void info(String msg) {
        if (isSpi) {
            spiLog.logIfEnabled(FQCN, Level.INFO, MARKER, msg);
        } else {
            this.log.info(MARKER, msg);
        }
    }

    @Override
    public void info(String msg, Object... param) {
        if (isSpi) {
            spiLog.logIfEnabled(FQCN, Level.INFO, MARKER, msg);
        } else {
            this.log.info(MARKER, msg, param);
        }
    }

    @Override
    public void debug(String msg) {
        if (isSpi) {
            spiLog.logIfEnabled(FQCN, Level.DEBUG, MARKER, msg);
        } else {
            this.log.debug(MARKER, msg);
        }
    }

    @Override
    public void debug(String msg, Object... param) {
        if (isSpi) {
            spiLog.logIfEnabled(FQCN, Level.DEBUG, MARKER, msg);
        } else {
            this.log.debug(MARKER, msg, param);
        }
    }

    @Override
    public void error(String msg, Throwable e) {
        if (isSpi) {
            spiLog.logIfEnabled(FQCN, Level.ERROR, MARKER, msg, e);
        } else {
            this.log.error(MARKER, msg, e);
        }
    }

    @Override
    public void setClass(Class<?> clazz) {
        setClassName(clazz.getName());
    }

    @Override
    public void setClassName(String className) {
        org.apache.logging.log4j.Logger log = LogManager.getLogger(className);
        if (isSpi) {
            AbstractLogger abstractLogger = (AbstractLogger) log;
            this.spiLog = new ExtendedLoggerWrapper(abstractLogger, abstractLogger.getName(), abstractLogger.getMessageFactory());
        } else {
            this.log = log;
        }
    }
}
